fix(tests): replace bun:test anti-patterns with idiomatic patterns - #512
Conversation
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds ADR-025 documenting Bun test parameterization and specific matcher conventions, plus validation feedback requiring TypeScript checks. Refactors command, engine, format, helper, and integration tests to use 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying archgate-cli with
|
| Latest commit: |
9e0aa8c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://226dc6a3.archgate-cli.pages.dev |
| Branch Preview URL: | https://claude-warm-watching-holleri.archgate-cli.pages.dev |
…tion and matchers Across 41 test files, converts manual for-loops that defined test cases or asserted per-item into test.each()/describe.each(), replaces generic expect(x).toBe(true/false) boolean checks with specific matchers, hoists duplicated per-test setup/teardown into beforeEach/afterEach, and replaces ad-hoc `if (...) return;` skip guards with test.skipIf(). Adds one missing error-path test (signup.test.ts). Found via an audit against https://bun.com/docs/test/writing-tests; all 86 fixes independently re-verified with no coverage loss and a clean `bun run validate`. Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…atchers Codifies two anti-patterns found across 24 test files during this session's audit: manual loops standing in for test.each()/ describe.each(), and generic boolean assertions (expect(x).toBe(true)) instead of specific matchers. Kept separate from ARCH-005, which is already at its review-context briefing-budget ceiling. Automated enforcement (a candidate oxlint plugin) is not yet implemented; rules is false and manual review is the enforcement layer for now. Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…ness Verify subagents on a large test-refactor workflow self-reported clean after lint+test but missed a TS6133 unused-parameter error only tsc --build caught -- future verify passes on TS changes must run typecheck too. Also notes that files written under /tmp during this session intermittently disappeared between tool calls; a real Windows temp path proved stable instead. Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
012254c to
909a00a
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
Code Coverage
Full HTML report available in workflow artifacts. Per-directory breakdown
|
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/engine/runner-ast-base.test.ts (1)
267-290: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAssert that each AST comparison actually ran.
runChecks()captures a thrownctx.ast()failure in the rule result. Since both structures start asundefined, an error can make this equality assertion pass without comparing ASTs. This weakens required ARCH-022 base-revision coverage.
tests/engine/runner-ast-base.test.ts#L267-L290: assert the rule has no error and both structures are defined before comparing them.tests/engine/runner-ast-base.test.ts#L300-L323: assert the rule has no error and both structures are defined before comparing them.As per path instructions,
tests/engine/{runner-ast,runner-ast-base,runner-ast-comments,ast-support}.test.tsmust maintain behavioral coverage for AST parsing and base-revision semantics.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/engine/runner-ast-base.test.ts` around lines 267 - 290, Strengthen both AST comparison tests in tests/engine/runner-ast-base.test.ts at lines 267-290 and 300-323: after runChecks, assert the rule result has no error and that both captured AST structures are defined before comparing them. Apply the same guards to each site so ctx.ast failures cannot make an undefined-to-undefined equality assertion pass.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md:
- Around line 12-23: Remove the unsupported point-in-time counts and limits
throughout this ADR, including the instance totals, affected-file totals, line
count, and briefing character limit. Preserve the qualitative rationale
describing recurring manual-loop and boolean-assertion patterns, and update any
related quantitative references in the Alternatives and Compliance/Enforcement
sections consistently.
- Around line 6-7: Update ARCH-025’s frontmatter scope, Decision, and Manual
Enforcement reviewer-duty clauses to consistently target tests/**/*.test.ts,
excluding fixture and fixture-rule files from the ADR’s applicability.
- Line 46: Update the matcher guidance in ARCH-025 so the inline code span for
the find expression contains no internal spacing, while preserving the
surrounding matcher examples and wording.
In `@tests/commands/session-context.test.ts`:
- Around line 135-151: Update the parameterized assertion in the session-context
command test to use a direct array-content matcher: assert opts contains
"--root" when hasRoot is true and does not contain it otherwise, without
comparing opts.includes("--root") to hasRoot.
In `@tests/engine/git-files.test.ts`:
- Around line 98-100: Replace the node:fs writeFileSync calls in the test setup
hooks, including the fixtures near the git commit setup and the corresponding
hooks, with awaited Bun.write() calls. Preserve each fixture’s existing path and
contents while keeping the setup behavior unchanged.
In `@tests/engine/runner-ast-cache.test.ts`:
- Line 82: Replace the looped per-result assertions in the affected tests with a
direct assertion against the expected error array, or parameterize the cases
with test.each so each result is asserted independently. Update both assertion
sites in the runner AST cache tests while preserving the existing expected
outcomes and avoiding for or forEach loops.
In `@tests/helpers/init-base-branch.test.ts`:
- Line 15: Replace the writeFileSync fixture creation in the init-base-branch
test setup with Bun.write(), preserving the same target path and file contents.
In `@tests/helpers/signup.test.ts`:
- Around line 116-127: Move globalThis.fetch restoration out of the inline
try/finally in the rejection test and into the file’s or suite’s afterEach hook,
following the centralized pattern used by tests such as auth.test.ts. Preserve
the direct fetch mock and ensure afterEach restores the original implementation
after every test.
---
Outside diff comments:
In `@tests/engine/runner-ast-base.test.ts`:
- Around line 267-290: Strengthen both AST comparison tests in
tests/engine/runner-ast-base.test.ts at lines 267-290 and 300-323: after
runChecks, assert the rule result has no error and that both captured AST
structures are defined before comparing them. Apply the same guards to each site
so ctx.ast failures cannot make an undefined-to-undefined equality assertion
pass.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3b976687-61ad-423e-8db1-9e340155823f
📒 Files selected for processing (44)
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md.claude/agent-memory/archgate-developer/MEMORY.md.claude/agent-memory/archgate-developer/feedback_verify_agents_run_typecheck.mdtests/commands/adr/create.test.tstests/commands/adr/list.test.tstests/commands/review-context.test.tstests/commands/session-context.test.tstests/commands/session-context/claude-code.test.tstests/commands/session-context/copilot.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/opencode.test.tstests/commands/upgrade.test.tstests/engine/check-case.test.tstests/engine/git-files.test.tstests/engine/reporter.test.tstests/engine/rule-scanner-escapes.test.tstests/engine/rule-scanner-positions.test.tstests/engine/rule-scanner.test.tstests/engine/runner-ast-base.test.tstests/engine/runner-ast-cache.test.tstests/engine/runner-ast.test.tstests/engine/runner-gitignore.test.tstests/engine/yaml-utils.test.tstests/formats/project-config-fuzz.test.tstests/helpers/adr-import.test.tstests/helpers/auth.test.tstests/helpers/binary-upgrade.test.tstests/helpers/claude-settings.test.tstests/helpers/credential-store.test.tstests/helpers/doctor.test.tstests/helpers/editor-detect.test.tstests/helpers/init-base-branch.test.tstests/helpers/install-info.test.tstests/helpers/pack-recommend.test.tstests/helpers/session-context.test.tstests/helpers/signup.test.tstests/helpers/stack-detect-frameworks.test.tstests/helpers/stack-detect.test.tstests/helpers/user-error.test.tstests/helpers/vscode-settings.test.tstests/integration/adr.test.tstests/integration/check.test.tstests/integration/clean.test.tstests/integration/review-context.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Cloudflare Pages
⚠️ CI failures not shown inline (6)
GitHub Actions: Validate / Lint, Test & Check: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run echo "$PR_TITLE" | bun run commitlint
�[36;1mecho "$PR_TITLE" | bun run commitlint�[0m
shell: /usr/bin/bash -e {0}
env:
ARCHGATE_TELEMETRY: 0
PR_TITLE: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
##[endgroup]
�[90m⧗�[39m --- input ---
�[1mAdd ADR briefing-budget enforcement; fix bun:test anti-patterns�[22m
�[31m✖�[39m subject may not be empty �[90m[subject-empty]�[39m
�[31m✖�[39m type may not be empty �[90m[type-empty]�[39m
�[1m�[31m✖�[39m found 2 problems, 0 warnings�[22m
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
error: "commitlint" exited with code 1
##[error]Process completed with exit code 1.
GitHub Actions: Validate / Validate Code: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run # shim-tests is skipped when no shim files changed — treat skipped as success.
�[36;1m# shim-tests is skipped when no shim files changed — treat skipped as success.�[0m
�[36;1mSHIM_OK="skipped"�[0m
�[36;1mif [[ "$SHIM_OK" == "skipped" ]]; then SHIM_OK="success"; fi�[0m
�[36;1m�[0m
�[36;1mif [[ "failure" != "success" ]] || \�[0m
�[36;1m [[ "$SHIM_OK" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "skipped" != "success" ]]; then�[0m
�[36;1m echo "::error::One or more jobs failed:"�[0m
GitHub Actions: Validate / 0_Validate Code.txt: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run # shim-tests is skipped when no shim files changed — treat skipped as success.
�[36;1m# shim-tests is skipped when no shim files changed — treat skipped as success.�[0m
�[36;1mSHIM_OK="skipped"�[0m
�[36;1mif [[ "$SHIM_OK" == "skipped" ]]; then SHIM_OK="success"; fi�[0m
�[36;1m�[0m
�[36;1mif [[ "failure" != "success" ]] || \�[0m
�[36;1m [[ "$SHIM_OK" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "success" != "success" ]] || \�[0m
�[36;1m [[ "skipped" != "success" ]]; then�[0m
�[36;1m echo "::error::One or more jobs failed:"�[0m
GitHub Actions: Validate / Smoke Test (Linux) _ Linux: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run if [ -z "$ARCHGATE_VERSION" ]; then
�[36;1mif [ -z "$ARCHGATE_VERSION" ]; then�[0m
�[36;1m # Find the newest release that already has the Linux asset uploaded.�[0m
�[36;1m # On release-commit pushes the Validate and Release workflows start�[0m
�[36;1m # concurrently, so the latest tag may exist before its binaries are�[0m
�[36;1m # uploaded by release-binaries.yml — hitting a 404.�[0m
�[36;1m asset="archgate-linux-x64.tar.gz"�[0m
�[36;1m tags="$(gh release list --limit 5 --json tagName --jq '.[].tagName' 2>/dev/null || true)"�[0m
�[36;1m if [ -z "$tags" ]; then�[0m
�[36;1m echo "::warning::No releases found, skipping install.sh smoke test"�[0m
�[36;1m exit 0�[0m
�[36;1m fi�[0m
�[36;1m found=""�[0m
�[36;1m for tag in $tags; do�[0m
�[36;1m assets="$(gh release view "$tag" --json assets --jq '.assets[].name' 2>/dev/null || true)"�[0m
�[36;1m if echo "$assets" | grep -qF "$asset"; then�[0m
�[36;1m ARCHGATE_VERSION="$tag"�[0m
�[36;1m found=1�[0m
�[36;1m break�[0m
�[36;1m fi�[0m
�[36;1m done�[0m
�[36;1m if [ -z "$found" ]; then�[0m
�[36;1m echo "::warning::No release with $asset found, skipping install.sh smoke test"�[0m
�[36;1m exit 0�[0m
�[36;1m fi�[0m
�[36;1m export ARCHGATE_VERSION�[0m
�[36;1mfi�[0m
�[36;1mecho "Testing install.sh with version $ARCHGATE_VERSION"�[0m
�[36;1m�[0m
�[36;1mARCHGATE_INSTALL_DIR="$(mktemp -d)"�[0m
�[36;1mexport ARCHGATE_INSTALL_DIR�[0m
�[36;1m�[0m
�[36;1msh install.sh�[0m
�[36;1m�[0m
�[36;1mif [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then�[0m
�[36;1m echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install"�[0m
GitHub Actions: Validate / 3_Lint, Test & Check.txt: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run echo "$PR_TITLE" | bun run commitlint
�[36;1mecho "$PR_TITLE" | bun run commitlint�[0m
shell: /usr/bin/bash -e {0}
env:
ARCHGATE_TELEMETRY: 0
PR_TITLE: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
##[endgroup]
�[90m⧗�[39m --- input ---
�[1mAdd ADR briefing-budget enforcement; fix bun:test anti-patterns�[22m
�[31m✖�[39m subject may not be empty �[90m[subject-empty]�[39m
�[31m✖�[39m type may not be empty �[90m[type-empty]�[39m
�[1m�[31m✖�[39m found 2 problems, 0 warnings�[22m
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
error: "commitlint" exited with code 1
##[error]Process completed with exit code 1.
GitHub Actions: Validate / 5_Smoke Test (Linux) _ Linux.txt: Add ADR briefing-budget enforcement; fix bun:test anti-patterns
Conclusion: failure
##[group]Run if [ -z "$ARCHGATE_VERSION" ]; then
�[36;1mif [ -z "$ARCHGATE_VERSION" ]; then�[0m
�[36;1m # Find the newest release that already has the Linux asset uploaded.�[0m
�[36;1m # On release-commit pushes the Validate and Release workflows start�[0m
�[36;1m # concurrently, so the latest tag may exist before its binaries are�[0m
�[36;1m # uploaded by release-binaries.yml — hitting a 404.�[0m
�[36;1m asset="archgate-linux-x64.tar.gz"�[0m
�[36;1m tags="$(gh release list --limit 5 --json tagName --jq '.[].tagName' 2>/dev/null || true)"�[0m
�[36;1m if [ -z "$tags" ]; then�[0m
�[36;1m echo "::warning::No releases found, skipping install.sh smoke test"�[0m
�[36;1m exit 0�[0m
�[36;1m fi�[0m
�[36;1m found=""�[0m
�[36;1m for tag in $tags; do�[0m
�[36;1m assets="$(gh release view "$tag" --json assets --jq '.assets[].name' 2>/dev/null || true)"�[0m
�[36;1m if echo "$assets" | grep -qF "$asset"; then�[0m
�[36;1m ARCHGATE_VERSION="$tag"�[0m
�[36;1m found=1�[0m
�[36;1m break�[0m
�[36;1m fi�[0m
�[36;1m done�[0m
�[36;1m if [ -z "$found" ]; then�[0m
�[36;1m echo "::warning::No release with $asset found, skipping install.sh smoke test"�[0m
�[36;1m exit 0�[0m
�[36;1m fi�[0m
�[36;1m export ARCHGATE_VERSION�[0m
�[36;1mfi�[0m
�[36;1mecho "Testing install.sh with version $ARCHGATE_VERSION"�[0m
�[36;1m�[0m
�[36;1mARCHGATE_INSTALL_DIR="$(mktemp -d)"�[0m
�[36;1mexport ARCHGATE_INSTALL_DIR�[0m
�[36;1m�[0m
�[36;1msh install.sh�[0m
�[36;1m�[0m
�[36;1mif [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then�[0m
�[36;1m echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install"�[0m
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx,js,jsx,mjs,cjs}
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-006-dependency-policy.md)
**/*.{ts,tsx,js,jsx,mjs,cjs}: Use Bun built-ins for file I/O (Bun.file,Bun.write), HTTP, subprocess execution (Bun.spawn), globbing (Bun.Glob), and testing (bun:test).
Do not use Node.js-specific APIs when Bun alternatives exist; for example, useBun.file()instead offs.readFile()for simple reads.
Prefernode:built-in modules such asnode:util,node:path, andnode:fsover npm alternatives.
Do not use utility libraries for single functions, such as importing lodash for one helper likepick.
Do not use path aliases (tsconfig paths); use relative imports with Bun's native module resolution.
Do not install packages globally during development; usebunxfor one-off tools.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
tests/**/*.ts
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-009-platform-detection-helper.md)
In test files, use
_resetPlatformCache()to simulate different platforms instead of mocking or mutatingprocess.platformdirectly.
tests/**/*.ts: Use Bun's built-inbun:testrunner for all tests; do not import test utilities fromnode:test.
Shared test helpers must also userestoreEnvwhen restoring environment variables.
tests/**/*.ts: In Bun tests, usetest.each()when the same assertion logic runs against multiple independent inputs, so each case is independently reported.
Usedescribe.each()when each parametrized case requires multiple related tests.
Use array rows for positional test-case arguments and object rows with$fieldtitle formatting when named fields improve readability.
Do not useforor.forEachloops to registertest(),it(), ordescribe()cases, or to run independent per-item assertions inside one test; usetest.each()ordescribe.each()instead.
Assert comparisons directly on the compared values, such asexpect(actual).toBe(expected)or.toEqual(expected), rather than asserting a derived boolean with.toBe(true)or.toBe(false).
Use specific matchers for derived facts:.toContain()or.toMatch()for content,.toBeInstanceOf(Array)for array type checks,.toHaveLength()for counts, and.find(...)with.toBeDefined()or.toBeUndefined()for existence checks.
Do not assertarr.some(...),arr.every(...),Array.isArray(...), or equivalent precomputed booleans with.toBe(true)/.toBe(false); use a matcher that exposes the underlying value or condition.
When converting a manual loop totest.each()ordescribe.each(), preserve every per-iteration assertion without dropping or merging assertions.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
{src,tests}/**/*.ts
📄 CodeRabbit inference engine (.archgate/adrs/LEGAL-001-spdx-license-headers.md)
{src,tests}/**/*.ts: Every TypeScript source file insrc/andtests/must begin with// SPDX-License-Identifier: Apache-2.0followed by// Copyright 2026 Archgate.
If a TypeScript file has a shebang line (for example#!/usr/bin/env buninsrc/cli.ts), the SPDX license header must appear immediately after the shebang.
Use single-line//comments for the SPDX header; do not use block comments (/* */) or alternate license identifiers.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
tests/**/*.test.ts
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-005-testing-standards.md)
tests/**/*.test.ts: Place tests intests/mirroring thesrc/directory structure, and name test files with the.test.tssuffix.
Test public module interfaces rather than private implementation details, use descriptive test names, and do not depend on network access.
Use isolated temporary directories created withmkdtempfor filesystem tests, and clean them up inafterEachorafterAll. Do not use hardcoded user or system paths.
Close external SDK instances such as servers, clients, and transports inafterEachorafterAll; manage their lifecycle in test hooks rather than individual test bodies.
When a temporary git repository performs commits, configure localuser.emailanduser.nameimmediately aftergit init; do not rely on global git identity.
Every runnabletest()orit()must contain at least oneexpect()assertion. Make implicit no-throw contracts explicit withnot.toThrow()orresolves.toBeUndefined(). Usetest.skiportest.todofor intentional placeholders.
Usetest.skipIf(condition),test.skip, ortest.todofor conditional or intentionally disabled tests; do not use bare early returns or empty callbacks to skip tests, and do not skip without a tracking issue.
When adding assertions to an older test file, importexpectfrombun:test.
Mock HTTP requests by assigning directly toglobalThis.fetch, and restore the original fetch implementation or mock inafterEach; do not mocknode:fetch.
Mock first-party modules withimport * as modandspyOn(mod, "fn"), restoring spies after each test; do not use process-globalmock.module()for first-party modules.
Wrap inlinespyOnormockImplementationusage intry/finallysomockRestore()always runs, or manage spies inbeforeEachandafterEach.
When redirecting user-scope paths, mocknode:os'shomedir()rather than relying on runtimeHOMEoverrides; use environment overrides only for code that reads environment variables directly at call time.
Re...
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
{src,tests,lint,scripts,shims}/**/*.ts
📄 CodeRabbit inference engine (.archgate/adrs/GEN-004-concise-forward-only-code-comments.md)
{src,tests,lint,scripts,shims}/**/*.ts: Project-authored TypeScript comments must contain no more than five lines of narrative prose in a contiguous whole-line comment run. Structural TSDoc sections such as@param,@returns,@throws, and@exampleare exempt.
Comments in project-authored TypeScript must describe current behavior only and must not narrate historical changes, previous implementations, relocations, migrations, or refactors.
Use structured TSDoc tags for parameter, return, thrown-error, and usage documentation rather than expanding summary prose; prose-container tags such as@remarks,@description,@notes,@todo, and@fixmestill count toward the five-line limit.
Long explanations and deep rationale belong in an ADR, issue, PR, or.claude/agent-memory/file, with the code comment pointing to that fuller reference.
Suppressions such asarchgate-ignoreandoxlint-disablemay be used only for genuine false positives and must include a stated reason.
The same comment invariants and structured-TSDoc tag lists must remain synchronized between the oxlint rules in.archgate/lint/oxlint.tsand the companion Archgate rules.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Bun rather than Node.js APIs or runtime assumptions; maintain strict TypeScript, ESNext, and ES module compatibility.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ts: UsestyleText()fromnode:utilfor output, support--jsonfor machine-readable output, emit no emoji, and use exit codes 0 for success, 1 for violations, 2 for internal errors, and 130 for user cancellation.
Prefer Bun built-ins and keep dependencies minimal.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
**
⚙️ CodeRabbit configuration file
**: This project uses Archgate — an AI governance framework based on
Architecture Decision Records (ADRs). The ADRs in.archgate/adrs/
are the authoritative rules for this codebase. Each ADR has a companion
.rules.tsfile with automated checks that run viaarchgate check.When reviewing, you must:
- Treat ADR violations as blocking issues, not suggestions.
- Cite the specific ADR ID when flagging a violation (e.g., "Violates ARCH-006").
- Focus on semantic and contextual violations that automated rules cannot catch —
the.rules.tsfiles already cover syntactic/structural patterns.- If you are unsure whether something violates an ADR, flag it as a question
rather than approving it.
Files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
tests/engine/{runner-ast,runner-ast-base,runner-ast-comments,ast-support}.test.ts
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-022-ast-aware-rule-context.md)
Maintain behavioral coverage for AST parsing, base-revision semantics, comment extraction, isolation, source locations, and throw-versus-null behavior.
Files:
tests/engine/runner-ast.test.tstests/engine/runner-ast-base.test.ts
tests/helpers/editor-detect.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Update editor detection tests, including expected list length and editor ID order, when adding a new editor.
Files:
tests/helpers/editor-detect.test.ts
tests/engine/rule-scanner-escapes.test.ts
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-024-rule-file-sandbox-boundary.md)
tests/engine/rule-scanner-escapes.test.ts: Every discovered scanner escape must first receive a failing regression test, and the escape suite must assert that attack payloads are blocked across imports, globals, constructor access, obfuscation, and exotic AST nodes.
Obfuscation fixtures must be constructed so formatter normalization cannot remove the escape, and must include a guard proving the fixture is still obfuscated.
Files:
tests/engine/rule-scanner-escapes.test.ts
tests/helpers/adr-import.test.ts
📄 CodeRabbit inference engine (.archgate/adrs/ARCH-024-rule-file-sandbox-boundary.md)
Test that
writeImportedAdrs()rejects imported rules reaching prohibited capabilities and writes neither the rule nor ADR markdown.
Files:
tests/helpers/adr-import.test.ts
🧠 Learnings (11)
📚 Learning: 2026-07-15T22:55:51.978Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 476
File: tests/helpers/telemetry-config.test.ts:24-28
Timestamp: 2026-07-15T22:55:51.978Z
Learning: In this Bun/TypeScript codebase, when a unit under test spawns subprocesses via Bun.spawn (e.g., running `git credential ...`), prefer overriding relevant env vars (such as `HOME`, `GIT_CONFIG_GLOBAL`, `GIT_CONFIG_NOSYSTEM`) using `process.env` in the test and restoring them with the test utility (e.g., `restoreEnv` from `tests/test-utils.ts`). Avoid relying on `spyOn(os, 'homedir')` for this purpose, because it only affects in-process calls and does not change the environment inherited by subprocesses; env-var overrides should be used for subprocess-level isolation and must be applied at call time.
Applied to files:
tests/helpers/user-error.test.tstests/helpers/doctor.test.tstests/helpers/claude-settings.test.tstests/helpers/vscode-settings.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/helpers/editor-detect.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/helpers/binary-upgrade.test.tstests/helpers/session-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.ts
📚 Learning: 2026-07-15T22:56:35.415Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 476
File: tests/commands/clean.test.ts:61-62
Timestamp: 2026-07-15T22:56:35.415Z
Learning: When reviewing tests that rely on src/helpers/paths.ts `internalPath()`, note that `internalPath()` intentionally reads `Bun.env.HOME ?? Bun.env.USERPROFILE` at call time and only uses `os.homedir()` if neither env var is set. Therefore, don’t suggest changing tests to `spyOn(os, "homedir")` for this behavior; instead, use per-test `Bun.env.HOME` / `Bun.env.USERPROFILE` overrides (as applicable) so the tests control `internalPath()`’s inputs.
Applied to files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/helpers/doctor.test.tstests/helpers/claude-settings.test.tstests/helpers/vscode-settings.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/helpers/editor-detect.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/helpers/session-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/commands/upgrade.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/commands/session-context/claude-code.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
📚 Learning: 2026-07-25T00:05:58.884Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 496
File: tests/helpers/auth.test.ts:38-46
Timestamp: 2026-07-25T00:05:58.884Z
Learning: When reviewing the Archgate CLI repository’s GEN-004 “concise forward-only narration” comments, don’t rely only on the automated phrase-based narration checks. Those checks can pass even when the comment wording describes historical/transfer semantics rather than current behavior (e.g., saying a prior restore “leaked” a value or a later subprocess “inherited it”). Manually verify that the comment describes the code’s current, forward behavior; flag or adjust comments that imply past/historical state transfer even if GEN-004 enforcement passes.
Applied to files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
📚 Learning: 2026-07-25T00:05:59.109Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 496
File: src/cli.ts:0-0
Timestamp: 2026-07-25T00:05:59.109Z
Learning: Code comments may include a concise issue/PR reference (per GEN-004) when it’s used to point readers to fuller rationale instead of inlining that rationale. During review, flag surrounding comment prose that reads like historical context or narrates refactors/relocations; a bare GEN-004-style reference is allowed and should not be flagged by itself.
Applied to files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
📚 Learning: 2026-07-25T15:44:40.668Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 501
File: .archgate/adrs/ARCH-005-testing-standards.md:0-0
Timestamp: 2026-07-25T15:44:40.668Z
Learning: In Archgate CLI test code governed by ARCH-007, only allow `Bun.$` in test suites that are explicitly restricted to a single platform. Any cross-platform test that runs on Linux, macOS, and Windows must avoid `Bun.$` and instead use array-based `Bun.spawn`. For shared git setup used by tests, import and use the `git()` helper from `tests/test-utils.ts` rather than duplicating git setup logic.
Applied to files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
📚 Learning: 2026-07-25T22:03:14.216Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 501
File: .archgate/adrs/ARCH-002-error-handling.md:0-0
Timestamp: 2026-07-25T22:03:14.216Z
Learning: In Archgate boundary-wrapped CLI command actions (the handlers that rely on `handleCommandError()` for user-facing error output), expected-failure guards should signal user errors by throwing `new UserError(<message/details>)` rather than directly calling `logError()` followed by `exitWith(1)`. This keeps user-facing logging and the exit path centralized in `handleCommandError()`. For normal/computed command outcomes (e.g., `const exitCode = getExitCode(await runChecks(...))`), use `await exitWith(exitCode)` instead of calling `process.exit(exitCode)` so telemetry/Sentry flushing and outcome tagging still run.
Applied to files:
tests/helpers/user-error.test.tstests/commands/review-context.test.tstests/integration/clean.test.tstests/helpers/doctor.test.tstests/engine/rule-scanner-positions.test.tstests/integration/adr.test.tstests/helpers/claude-settings.test.tstests/engine/runner-ast.test.tstests/helpers/vscode-settings.test.tstests/engine/yaml-utils.test.tstests/engine/check-case.test.tstests/helpers/init-base-branch.test.tstests/helpers/credential-store.test.tstests/integration/check.test.tstests/helpers/editor-detect.test.tstests/engine/runner-gitignore.test.tstests/helpers/install-info.test.tstests/helpers/signup.test.tstests/commands/session-context.test.tstests/helpers/binary-upgrade.test.tstests/engine/reporter.test.tstests/helpers/session-context.test.tstests/integration/review-context.test.tstests/helpers/stack-detect-frameworks.test.tstests/commands/session-context/opencode.test.tstests/engine/rule-scanner-escapes.test.tstests/commands/upgrade.test.tstests/formats/project-config-fuzz.test.tstests/commands/session-context/cursor.test.tstests/commands/session-context/copilot.test.tstests/engine/runner-ast-cache.test.tstests/commands/session-context/claude-code.test.tstests/engine/runner-ast-base.test.tstests/engine/rule-scanner.test.tstests/engine/git-files.test.tstests/commands/adr/list.test.tstests/helpers/auth.test.tstests/helpers/adr-import.test.tstests/helpers/pack-recommend.test.tstests/helpers/stack-detect.test.tstests/commands/adr/create.test.ts
📚 Learning: 2026-06-11T12:50:28.661Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 406
File: .claude/agent-memory/archgate-developer/feedback_prefer_tests_over_adr_rules.md:8-18
Timestamp: 2026-06-11T12:50:28.661Z
Learning: In `archgate/cli`, for markdown files under `.claude/agent-memory/`, follow the established convention: use YAML frontmatter (with a `name:` field used as the document title) and do not require a top-level `#` (H1) heading. During code review, do not flag missing first-line/first-top-level H1 headings (e.g., MD041) for these agent-memory files since markdownlint is not part of the repo’s `bun run validate` lint pipeline (oxlint/oxfmt only).
Applied to files:
.claude/agent-memory/archgate-developer/feedback_verify_agents_run_typecheck.md.claude/agent-memory/archgate-developer/MEMORY.md
📚 Learning: 2026-07-25T00:05:20.592Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 496
File: .claude/agent-memory/archgate-developer/project_test_isolation_gotchas.md:10-10
Timestamp: 2026-07-25T00:05:20.592Z
Learning: When reviewing documentation/agent-memory entries under `.claude/agent-memory/**`, do not enforce GEN-004’s “forward-only” comment/narrative requirement. These entries are allowed to keep historical/past-tense incident narratives and dated markers (e.g., `Found YYYY-MM-DD`) because the context is intended to help future agents evaluate edge cases. Outside this scope, GEN-004’s forward-only rule should still apply.
Applied to files:
.claude/agent-memory/archgate-developer/feedback_verify_agents_run_typecheck.md.claude/agent-memory/archgate-developer/MEMORY.md
📚 Learning: 2026-07-11T13:03:15.386Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 467
File: .archgate/adrs/ARCH-011-consistent-project-root-resolution.md:0-0
Timestamp: 2026-07-11T13:03:15.386Z
Learning: For Markdown files formatted by oxfmt (especially ADRs), avoid inline code spans that contain escaped backticks, e.g. `\`...\`` inside a single `` `...` `` span. oxfmt may mis-parse these and, on re-format, can collapse spaces after later inline code spans on the same line, effectively removing any manually re-added spacing. Instead, rephrase the text so the message stays plain quoted text, and put any embedded command/fragment that needs code formatting (e.g., `archgate init`) in its own separate inline code span; keep surrounding punctuation/spacing outside the code span.
Applied to files:
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md
📚 Learning: 2026-07-25T16:24:51.133Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 501
File: .archgate/adrs/ARCH-003-output-formatting.md:0-0
Timestamp: 2026-07-25T16:24:51.133Z
Learning: In Archgate ADRs (.archgate/adrs/*.md), omit quantitative claims (e.g., token savings, benchmarks, performance deltas) unless they are backed by a reproducible measurement and supported by a single cited reference. If you cannot satisfy both (reproducible measurement + exactly one cited reference), describe the benefit qualitatively and tie it to the relevant policy/requirements instead of using numeric estimates.
Applied to files:
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md
📚 Learning: 2026-07-25T22:03:17.073Z
Learnt from: rhuanbarreto
Repo: archgate/cli PR: 501
File: .archgate/adrs/ARCH-015-cli-command-documentation-coverage.md:17-18
Timestamp: 2026-07-25T22:03:17.073Z
Learning: When updating an ADR that documents rule discovery/enforcement behavior, ensure the ADR’s stated discovery contract matches the implementation in code. If the rule only discovers commands by scanning `src/commands/*.ts` and `src/commands/*/index.ts`, the ADR must not claim it also inspects command registration calls elsewhere (e.g., `src/cli.ts`). Any ADR language that changes the documented contract should be treated as a normative change to behavior and aligned with the corresponding implementation/issue, not as prose-only documentation compression.
Applied to files:
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md
🪛 ast-grep (0.44.1)
tests/engine/check-case.test.ts
[warning] 103-103: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(Unknown case scheme "${inherited}", "u")
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
🪛 LanguageTool
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md
[style] ~17-~17: Consider an alternative for the overused word “exactly”.
Context: ... any existing automated check, which is exactly why they spread undetected across 24 in...
(EXACTLY_PRECISELY)
[style] ~44-~44: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ated tests, not just one assertion. - DO pass array rows ([a, b, expected]) ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~45-~45: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...s (format the title with $field). - DO assert a derived comparison directly ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~46-~46: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...expect(actual).toEqual(expected). - DO use the matcher that matches the shap...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~53-~53: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: .../ expect(a).not.toBe(b) directly. - DON'T write `expect(arr.some(predicate))...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.23.0)
.claude/agent-memory/archgate-developer/feedback_verify_agents_run_typecheck.md
[warning] 8-8: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
.archgate/adrs/ARCH-025-idiomatic-bun-test-parametrization-and-matchers.md
[warning] 46-46: Spaces inside code span elements
(MD038, no-space-in-code)
- tests/commands/session-context.test.ts: fix a real regression the
review caught -- the test.each conversion for --root asserted
opts.includes("--root") wrapped in .toBe(hasRoot), reintroducing the
exact boolean-derived-assertion anti-pattern ARCH-025 exists to ban.
Use expect(opts).toContain()/.not.toContain() instead.
- ARCH-025: narrow the files scope from tests/**/*.ts to
tests/**/*.test.ts so it doesn't apply to non-test fixture files
under tests/fixtures/**/*.rules.ts and tests/integration/cli-harness.ts.
- ARCH-025: drop the fragile "199 lines / 2000-char cap" claim about
ARCH-005's current size -- that's a fact about a different, mutable
file, not evidence for this one.
- ARCH-025: fix a malformed inline code span (MD038).
Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…ests CodeRabbit's outside-diff-range finding on PR #512: the earlier boolean-toBe fix hoisted baseStructure/headStructure as `unknown`, assigned only inside the rule's check() callback. If ctx.ast() throws, runChecks() captures that into result.error and both variables stay undefined -- expect(undefined).toEqual(undefined) then passes without ever comparing an AST. Assert result.results[0].error is undefined and both structures are defined before the equality check, for both the typescript and javascript comment-only-edit tests. Checked the same hoisted-variable-compared-via-toEqual shape across the rest of this PR's changed files: runner-ast-cache.test.ts's treeOne/treeTwo and runner-ast.test.ts's result already assert result.results[0].error is undefined first, and review-context.test.ts's parsed has its own try/catch with a descriptive throw -- none share this gap. Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
|
Re: the outside-diff-range finding on The earlier boolean-toBe fix hoisted I also swept the rest of this PR's changed files for the same hoisted-variable-compared-via- |
|
@coderabbitai review |
✅ Action performedReview finished.
|
- tests/helpers/signup.test.ts: CodeRabbit correctly pointed out ARCH-005 distinguishes globalThis.fetch mocking (must restore in afterEach) from spyOn/mockImplementation (try/finally explicitly permitted) -- the try/finally exception I'd cited doesn't cover the fetch-assignment pattern this file uses. Hoisted originalFetch into the describe block's beforeEach/afterEach for all 6 requestSignup tests, matching the pattern already established in auth.test.ts. - ARCH-025: replaced the audit's point-in-time instance/file counts with qualitative language, per this repo's established ADR convention (cited from PR #501) that quantitative claims need a reproducible measurement plus a single citable reference, not an ephemeral session count. Signed-off-by: Rhuan Barreto <rhuan@barreto.work>
…into claude/warm-watching-hollerith
# archgate ## [0.51.0](v0.50.0...v0.51.0) (2026-07-26) ### Features * **adrs:** enforce concise, forward-only code comments (GEN-004) ([#496](#496)) ([9a114b3](9a114b3)), references [#2123](https://github.com/archgate/cli/issues/2123) * **adrs:** flag stray files at the repository root (GEN-005) ([#535](#535)) ([6a6e765](6a6e765)), closes [#514](#514), references [#500](#500) * **engine:** add ctx.readYAML and ctx.checkCase rule helpers ([#497](#497)) ([c5d82c5](c5d82c5)), closes [#490](#490), references [#490](#490) [#491](#491) [#499](#499) [#499](#499) [#499](#499) [#499](#499) * report truncated ADR briefings, trim the ADR corpus 15.6%, add GEN-005 briefing budget ([#501](#501)) ([a9dab40](a9dab40)) ### Bug Fixes * **docs:** relocate ADR content to clear briefing-budget warnings ([#531](#531)) ([c7419b3](c7419b3)) * **docs:** restore pt-br diacritics and enforce locale content integrity ([#523](#523)) ([db39104](db39104)), closes [#516](#516), references [#231](#231) * **engine:** allow symlinks that resolve inside the project root ([#500](#500)) ([387bf15](387bf15)) * **engine:** reject rule-file reads through a symlinked ancestor directory ([#499](#499)) ([a555f9d](a555f9d)), references [#497](#497) [#491](#491) [#497](#497) [#497](#497) [#497](#497) [#497](#497) * **engine:** scan top-level export declarations with a null source ([#493](#493)) ([d07db03](d07db03)), closes [#491](#491) * **engine:** stop dropping AST nodes with exotic literal values ([#494](#494)) ([0015542](0015542)), closes [#493](#493) [#493](#493) * **lint:** resolve no-bare-env-restore by captured key and lexical scope ([#524](#524)) ([7094a3a](7094a3a)), closes [#498](#498) * **rules:** make ARCH-020 and ARCH-023 match ctx.ast() instead of raw text ([#533](#533)) ([ad5529b](ad5529b)), closes [#513](#513), references [#486](#486) * **tests:** replace bun:test anti-patterns with idiomatic patterns ([#512](#512)) ([bcb086f](bcb086f)) --- This PR was generated with [simple-release](https://github.com/TrigenSoftware/simple-release). <details> <summary>📄 Cheatsheet</summary> <br> You can configure the bot's behavior through a pull request comment using the `!simple-release/set-options` command. ### Command Format ````md !simple-release/set-options ```json { "bump": {}, "publish": {} } ``` ```` ### Useful Parameters #### Bump | Parameter | Type | Description | |-----------|------|-------------| | `version` | `string` | Force set specific version | | `as` | `'major' \| 'minor' \| 'patch' \| 'prerelease'` | Release type | | `prerelease` | `string` | Pre-release identifier (e.g., "alpha", "beta") | | `firstRelease` | `boolean` | Whether this is the first release | | `skip` | `boolean` | Skip version bump | | `byProject` | `Record<string, object>` | Per-project bump options for monorepos | #### Publish | Parameter | Type | Description | |-----------|------|-------------| | `skip` | `boolean` | Skip publishing | | `access` | `'public' \| 'restricted'` | Package access level | | `tag` | `string` | Tag for npm publication | ### Usage Examples #### Force specific version ````md !simple-release/set-options ```json { "bump": { "version": "2.0.0" } } ``` ```` #### Force major bump ````md !simple-release/set-options ```json { "bump": { "as": "major" } } ``` ```` #### Create alpha pre-release ````md !simple-release/set-options ```json { "bump": { "prerelease": "alpha" } } ``` ```` #### Publish with specific access and tag ````md !simple-release/set-options ```json { "bump": { "prerelease": "beta" }, "publish": { "access": "public", "tag": "beta" } } ``` ```` ### Custom Changelog Preamble You can add custom markdown to the top of the changelog (right after the version header) using the `!simple-release/set-preamble` command. The markdown after the command line becomes the preamble. ```md !simple-release/set-preamble ## What's new? - The website was completely redesigned - The new API gives you awesome possibilities ``` In a monorepo, pass the full package name after the command to target a single package's changelog. Wrap the name in backticks so GitHub keeps it as text instead of a mention: ```md !simple-release/set-preamble `@your-org/core` ## Core changes - New plugin system ``` Use one comment per package, plus one without a name for the whole release. ### Access Restrictions The commands can only be used by users with permissions: - repository owner - organization member - collaborator ### Notes - The last comment with `!simple-release/set-options` command takes priority - The last `!simple-release/set-preamble` comment per package takes priority - JSON must be valid, otherwise the `set-options` command will be ignored - Parameters apply only to the current release execution - The commands can be updated by editing the comment or adding a new one </details> <!-- Please do not edit this comment. simple-release-pull-request: true simple-release-branch-from: release simple-release-branch-to: main --> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary
Audited all 120
tests/**/*.test.tsfiles against Bun's own testing guidance (https://bun.com/docs/test/writing-tests) using parallel review agents, then fixed every confirmed finding and independently re-verified each fix.loop-based-tests(32, 8 files) — manualfor/.forEachloops that registered test cases or asserted per-item, converted totest.each()/describe.each().boolean-toBe(28, 16 files) —expect(x).toBe(true/false)on a derived boolean, converted to specific matchers (toBeInstanceOf,toContain,toMatch, per-item assertions, etc.).manual-setup-vs-hooks(16, 14 files) — duplicated per-test setup/teardown hoisted intobeforeEach/afterEach.other/missing-error-test(10, 8 files) — ad-hocif (...) return;skip guards replaced withtest.skipIf(), a swallowedprocess.exitassertion made explicit, and one new test added for an untested fetch-rejection error path.bun run typecheck, not just lint+test; and/tmpwrites were observed to be unreliable across tool calls in this session's environment.main's already-merged GEN-005 work (check-action.test.ts,adr-sections.test.ts, the 2 new tests appended toreview-context.test.ts) against the same anti-pattern criteria — all clean, no further fixes needed.This branch previously carried an unrelated, already-merged feature (the ADR briefing-budget work,
main#501) as leftover unmerged commits from a stale local copy; it has been rebased onto currentmainso this PR now contains only the 3 commits above.Test plan
bun run validatepasses clean (lint, typecheck, format, full test suite: 1800 pass / 0 fail,archgate check47/47, knip, build check)archgate:reviewerskill: APPROVED — 4 parallel domain reviews (Testing Standards ×3 batches + General/Process) against ARCH-005, GEN-004, LEGAL-001, all PASS with zero violationsgit diffby a second agent for coverage preservation (no assertions dropped/weakened) before being counted as donearchgate checkpasses with the new ARCH-025 ADR included (47/47, no new violations)